home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 5 / Skunkware 5.iso / src / X11 / tclMotif-1.4 / doc / tclMotif.doc < prev    next >
Text File  |  1995-06-29  |  48KB  |  1,495 lines

  1. <!OPS, Version = 8.0>
  2.  
  3. <!Page Number Stream,
  4.      Name =            "page",
  5.     Starting Page # =     Inherit>
  6.  
  7. <!Document,
  8.     Header Page =        no,
  9.     Final Output Device =    "ps",
  10.     Default Printer =    "nearest-ps",
  11.     Default Page Stream Name = "page">
  12.  
  13. <!Font Definitions,
  14.     F2 = Times 10,
  15.     F3 = Times 12,
  16.     F4 = Times 12 Italic,
  17.     F5 = Times 16 Bold,
  18.     F6 = Times 18 Bold,
  19.     F7 = Courier 12,
  20.     F8 = Times 14 Bold,
  21.     F9 = Thames 12,
  22.     F10 = Times 6,
  23.     F11 = Courier 16 Bold>
  24.  
  25. <!Page,
  26.     Bottom Margin =        1 Inches,
  27.     Left Margin =        1 Inches,
  28.     Right Margin =        1 Inches,
  29.     Hyphenation =        on,
  30.     Revision Bar Placement = Left>
  31.  
  32. <!Autonumber Stream, "ref#", 1,
  33.     Level 1 Suffix =    "">
  34.  
  35. <!Autonumber Stream, "section#", 1>
  36.  
  37. <!Autonumber Stream, "list", 1>
  38.  
  39. <!Autonumber Stream, "footnote", 1,
  40.     Level 1 Suffix =    "">
  41.  
  42. <!Autonumber Stream, "Outline", 3,
  43.     Level 1 Symbol Type =    Upper Roman,
  44.     Level 2 Symbol Type =    Upper Alpha>
  45.  
  46. <!Autonumber Stream, "List", 1>
  47.  
  48. <!Class, "a4:para",
  49.     Top Margin =        0.0393701 Inches,
  50.     Bottom Margin =        0.0393701 Inches,
  51.     Font =            F3@Z7@Lnl,
  52.     Line Spacing =        1.1606 lines,
  53.     Left Tab =        0/0.9844442/1.9685042/2.9527555 Inches,
  54.     Composition =        Optimum,
  55.     Lisp = "(tell *load-object* mid:put-data 'ileaf::saved-data 
  56. '(:form-lang nil :form-pagesize ""a4"")<#0a>
  57. )">
  58.  
  59. <!Class, "abstract",
  60.     Top Margin =        0.04 Inches,
  61.     Bottom Margin =        0.04 Inches,
  62.     Left Margin =        1.50 Inches,
  63.     Right Margin =        1.50 Inches,
  64.     Alignment =        Center,
  65.     Font =            F4@Z7@Lam,
  66.     Line Spacing =        1.1615 lines,
  67.     Left Tab =        0/1*3 Inches,
  68.     Composition =        Optimum>
  69.  
  70. <!Class, "abstracthead",
  71.     Top Margin =        0.04 Inches,
  72.     Bottom Margin =        0.04 Inches,
  73.     Left Margin =        0.50 Inches,
  74.     Right Margin =        0.50 Inches,
  75.     Alignment =        Center,
  76.     Font =            F5@Z7@Lam,
  77.     Line Spacing =        1.1615 lines,
  78.     Left Tab =        0/1*3 Inches,
  79.     Composition =        Optimum>
  80.  
  81. <!Class, "center",
  82.     Top Margin =        0.14 Inches,
  83.     Bottom Margin =        0 Inches,
  84.     Left Margin =        0.50 Inches,
  85.     Right Margin =        0.50 Inches,
  86.     Alignment =        Center,
  87.     Font =            F6@Z7@Lam,
  88.     Line Spacing =        1.3078 lines,
  89.     Left Tab =        0.5/0.5*29 Inches>
  90.  
  91. <!Class, "left",
  92.     Top Margin =        0.14 Inches,
  93.     Bottom Margin =        0 Inches,
  94.     Left Margin =        0.50 Inches,
  95.     Right Margin =        0.50 Inches,
  96.     Alignment =        Left,
  97.     Font =            F2@Z7@Lam,
  98.     Line Spacing =        1.3067 lines,
  99.     Left Tab =        0.5/0.5*29 Inches>
  100.  
  101. <!Class, "ltr:para",
  102.     Top Margin =        0.04 Inches,
  103.     Bottom Margin =        0.04 Inches,
  104.     Font =            F3@Z7@Lnl,
  105.     Line Spacing =        1.1606 lines,
  106.     Left Tab =        0/1*3 Inches,
  107.     Composition =        Optimum,
  108.     Lisp = "(tell *load-object* mid:put-data 'ileaf::saved-data 
  109. '(:form-lang nil :form-pagesize ""ltr"")<#0a>
  110. )">
  111.  
  112. <!Class, "para",
  113.     Top Margin =        0.04 Inches,
  114.     Bottom Margin =        0.04 Inches,
  115.     Left Margin =        0.50 Inches,
  116.     Right Margin =        0.50 Inches,
  117.     Font =            F3@Z7@Lam,
  118.     Line Spacing =        1.1615 lines,
  119.     Left Tab =        0/1*3 Inches,
  120.     Composition =        Optimum>
  121.  
  122. <!Class, "program",
  123.     Top Margin =        0.04 Inches,
  124.     Bottom Margin =        0.04 Inches,
  125.     Left Margin =        1 Inches,
  126.     Right Margin =        0.50 Inches,
  127.     Font =            F7@Z7@Lam,
  128.     Line Spacing =        1.1615 lines,
  129.     Left Tab =        0/1*3 Inches,
  130.     Composition =        Optimum>
  131.  
  132. <!Class, "reference",
  133.     Top Margin =        0.04 Inches,
  134.     Bottom Margin =        0.04 Inches,
  135.     Left Margin =        1 Inches,
  136.     Right Margin =        0.50 Inches,
  137.     First Indent =        -0.50 Inches,
  138.     Font =            F3@Z7@Lam,
  139.     Line Spacing =        1.1615 lines,
  140.     Left Tab =        0/1*3 Inches,
  141.     Composition =        Optimum,
  142.     Contents =        Prefix>
  143.  
  144. <"|:reference",
  145.     Hidden =        yes,
  146.     Font =            @i*,
  147.     Subcomponent =        yes,
  148.     Contents =        Shared><F0>[<Autonum, "ref#", 1, Value = "1">]<Tab>
  149. <End Sub><F0>
  150.  
  151. <!Class, "right",
  152.     Top Margin =        0.14 Inches,
  153.     Bottom Margin =        0 Inches,
  154.     Left Margin =        0.50 Inches,
  155.     Right Margin =        0.50 Inches,
  156.     Alignment =        Right,
  157.     Font =            F2@Z7@Lam,
  158.     Line Spacing =        1.3067 lines,
  159.     Left Tab =        0.5/0.5*29 Inches>
  160.  
  161. <!Class, "section",
  162.     Top Margin =        0.04 Inches,
  163.     Bottom Margin =        0.04 Inches,
  164.     Left Margin =        0.50 Inches,
  165.     Right Margin =        0.50 Inches,
  166.     Font =            F5@Z7@Lam,
  167.     Line Spacing =        1.1615 lines,
  168.     Left Tab =        0/1*3 Inches,
  169.     Composition =        Optimum,
  170.     Contents =        Prefix>
  171.  
  172. <"|:section",
  173.     Hidden =        yes,
  174.     Font =            @i*,
  175.     Subcomponent =        yes,
  176.     Contents =        Shared><F0><Autonum, "section#", 1> 
  177. <End Sub><F0>
  178.  
  179. <!Class, "subsection",
  180.     Top Margin =        0.04 Inches,
  181.     Bottom Margin =        0.04 Inches,
  182.     Left Margin =        0.50 Inches,
  183.     Right Margin =        0.50 Inches,
  184.     Font =            F8@Z7@Lam,
  185.     Line Spacing =        1.1615 lines,
  186.     Left Tab =        0/1*3 Inches,
  187.     Composition =        Optimum>
  188.  
  189. <!Class, "tbl:autonum",
  190.     Top Margin =        0.04 Inches,
  191.     Bottom Margin =        0.04 Inches,
  192.     Alignment =        Left,
  193.     Font =            F9@Z7@Lnl,
  194.     Line Spacing =        1.1606 lines,
  195.     Left Tab =        0/0.8*7 Inches,
  196.     Composition =        Optimum,
  197.     Lisp = "(tell *load-object* mid:put-data 'ileaf::saved-data 
  198. '(:form-lang nil :form-pagesize nil)<#0a>
  199. )">
  200.  
  201. <!Class, "tbl:cmpn",
  202.     Top Margin =        0.04 Inches,
  203.     Bottom Margin =        0.04 Inches,
  204.     Alignment =        Left,
  205.     Font =            F9@Z7@Lnl,
  206.     Line Spacing =        1.1606 lines,
  207.     Left Tab =        0/0.8*7 Inches,
  208.     Composition =        Optimum,
  209.     Lisp = "(tell *load-object* mid:put-data 'ileaf::saved-data 
  210. '(:form-lang nil :form-pagesize nil)<#0a>
  211. )">
  212.  
  213. <!Class, "tbl:frame",
  214.     Top Margin =        0.04 Inches,
  215.     Bottom Margin =        0.04 Inches,
  216.     Alignment =        Left,
  217.     Font =            F9@Z7@Lnl,
  218.     Line Spacing =        1.1606 lines,
  219.     Left Tab =        0/0.8*7 Inches,
  220.     Composition =        Optimum,
  221.     Lisp = "(tell *load-object* mid:put-data 'ileaf::saved-data 
  222. '(:form-lang nil :form-pagesize nil)<#0a>
  223. )">
  224.  
  225. <!Class, "tbl:pagefor",
  226.     Top Margin =        0.04 Inches,
  227.     Bottom Margin =        0.04 Inches,
  228.     Alignment =        Left,
  229.     Font =            F3@Z7@Lnl,
  230.     Line Spacing =        1.1606 lines,
  231.     Left Tab =        0/0.8*7 Inches,
  232.     Composition =        Optimum,
  233.     Lisp = "(tell *load-object* mid:put-data 'ileaf::saved-data 
  234. '(:form-lang nil :form-pagesize nil)<#0a>
  235. )">
  236.  
  237. <F10@Z7@Lnl>standard<Tab>ltr<Tab>a4<HR>
  238. top<Tab><Tab><HR>
  239. bottom<Tab><Tab><HR>
  240. left<Tab><Tab><HR>
  241. right<Tab><Tab><HR>
  242. <HR>
  243.  
  244. <!Class, "tbl:pagenum",
  245.     Top Margin =        0.04 Inches,
  246.     Bottom Margin =        0.04 Inches,
  247.     Alignment =        Left,
  248.     Font =            F9@Z7@Lnl,
  249.     Line Spacing =        1.1606 lines,
  250.     Left Tab =        0/0.8*7 Inches,
  251.     Composition =        Optimum,
  252.     Lisp = "(tell *load-object* mid:put-data 'ileaf::saved-data 
  253. '(:form-lang nil :form-pagesize nil)<#0a>
  254. )">
  255.  
  256. <!Class, "title",
  257.     Top Margin =        0.04 Inches,
  258.     Bottom Margin =        0.04 Inches,
  259.     Left Margin =        0.50 Inches,
  260.     Right Margin =        0.50 Inches,
  261.     Alignment =        Center,
  262.     Font =            F6@Z7@Lam,
  263.     Line Spacing =        1.1615 lines,
  264.     Left Tab =        0/1*3 Inches,
  265.     Composition =        Optimum>
  266.  
  267. <!Class, "|:para",
  268.     Top Margin =        0.0266667 Inches,
  269.     Bottom Margin =        0.0266667 Inches,
  270.     Font =            F3@Z7@Lam@i*,
  271.     Line Spacing =        1.162 lines,
  272.     Left Tab =        0/1*3 Inches,
  273.     Composition =        Optimum,
  274.     Contents =        Shared>
  275.  
  276. <!Class, "|:reference",
  277.     Top Margin =        0.0266667 Inches,
  278.     Bottom Margin =        0.0266667 Inches,
  279.     Font =            F3@Z7@Lam@i*,
  280.     Line Spacing =        1.162 lines,
  281.     Left Tab =        0/1*3 Inches,
  282.     Composition =        Optimum,
  283.     Contents =        Shared>
  284.  
  285. [<Autonum, "ref#", 1, Value = "1">]<Tab>
  286.  
  287. <!Class, "|:section",
  288.     Top Margin =        0.0266667 Inches,
  289.     Bottom Margin =        0.0266667 Inches,
  290.     Font =            F5@Z7@Lam@i*,
  291.     Line Spacing =        1.162 lines,
  292.     Left Tab =        0/1*3 Inches,
  293.     Composition =        Optimum,
  294.     Contents =        Shared>
  295.  
  296. <Autonum, "section#", 1> 
  297.  
  298. <!Master Frame,
  299.     Name =            "At Anchor",
  300.     Placement =        At Anchor,
  301.     Width =            0.41 Inches,
  302.     Height =        0.14 Inches,
  303.     Diagram =
  304. V11,
  305. (g9,0,0,)>
  306.  
  307. <!Master Frame,
  308.     Name =            "Auto",
  309.     Placement =        At Anchor,
  310.     Width =            1 Inches,
  311.     Height =        0.3329997 Inches,
  312.     Diagram =
  313. V11,
  314. (g9,0,0,)>
  315.  
  316. <!Master Frame,
  317.     Name =            "Bottom",
  318.     Placement =        Bottom of Page,
  319.     Horizontal Alignment =    Center,
  320.     Width =            6.50 Inches,
  321.     Height =        3.25 Inches,
  322.     Diagram =
  323. V11,
  324. (g9,0,0,)>
  325.  
  326. <!Master Frame,
  327.     Name =            "Following Anchor",
  328.     Placement =        Following Anchor,
  329.     Horizontal Alignment =    Center,
  330.     Width =            6.50 Inches,
  331.     Height =        3.25 Inches,
  332.     Diagram =
  333. V11,
  334. (g9,0,0,)>
  335.  
  336. <!Master Frame,
  337.     Name =            "Following Text",
  338.     Placement =        Following Text,
  339.     Horizontal Alignment =    Center,
  340.     Width =            6.50 Inches,
  341.     Height =        3.25 Inches,
  342.     Diagram =
  343. V11,
  344. (g9,0,0,)>
  345.  
  346. <!Master Frame,
  347.     Name =            "Footnote",
  348.     Placement =        Bottom of Page,
  349.     Horizontal Alignment =    Left,
  350.     Same Page =        yes,
  351.     Width =            6.50 Inches,
  352.     Height =        0.20 Inches,
  353.     Diagram =
  354. V11,
  355. (g9,0,0,)>
  356.  
  357. <!Master Frame,
  358.     Name =            "Top",
  359.     Placement =        Top of Page,
  360.     Horizontal Alignment =    Center,
  361.     Width =            6.50 Inches,
  362.     Height =        3.25 Inches,
  363.     Diagram =
  364. V11,
  365. (g9,0,0,)>
  366.  
  367. <!Master Frame,
  368.     Name =            "inline",
  369.     Placement =        At Anchor,
  370.     Width =            0.50 Inches,
  371.     Height =        0.1660002 Inches,
  372.     Diagram =
  373. V11,
  374. (g9,0,0,
  375.  (E16,0,0,,5,1,1,0.0533333,1,15,0,0,1,0,0,0,1,5,127,7,0,0,7,0,1,1,0.0666667,0.06
  376.   66667,6,6,0,0.0666667,6))>
  377.  
  378. <Page Header, Frame =
  379. V11,
  380. (g9,0,0,)>
  381.  
  382. <Page Footer, Frame =
  383. V11,
  384. (g9,1,0,
  385.  (t14,1,0,,0,0.5333333,0,7,0,0,,wst:timsps12,)
  386.  (t14,2,4,,3.2466667,0.5333333,1,7,0,0,,wst:timsps10,-\ \X80a0\ -))>
  387.  
  388. <!End Declarations>
  389.  
  390. <"title">
  391.  
  392. <|,"1">A Tcl Binding to Motif
  393.  
  394. <"title">
  395.  
  396. Jan Newmarch<HR>
  397. University of Canberra
  398.  
  399. <"abstracthead">
  400.  
  401. Abstract
  402.  
  403. <"abstract",
  404.     Alignment =        Both>
  405.  
  406. Tcl is a type-free interpreted language intended for <SR>
  407. use as an embedded command language for applica<SR>
  408. tions. Motif is the standard GUI for the X Window Sys<SR>
  409. tem, but this has a complex C-based API. This paper <SR>
  410. discusses a binding of tcl to Motif which allows for a <SR>
  411. simpler API.
  412.  
  413. <"section">
  414.  
  415. <"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, First = Yes, Value = "1."> 
  416. <End Sub><F0>Introduction
  417.  
  418. <"para">
  419.  
  420. The X Window System is now accepted as the standard windowing systems 
  421. for Unix <SR>
  422. graphics workstations and terminals. It provides a low-level set of 
  423. tools to build ap<SR>
  424. plications. Most applications now are built using a higher-level toolkit 
  425. which typi<SR>
  426. cally supplies objects usually known as widgets. There are a number 
  427. of such toolkits, <SR>
  428. but the one that has achieved the major success is the Motif toolkit 
  429. based on the Xt <SR>
  430. Intrinsics. Motif has defined a look-and-feel that is copied to a 
  431. greater or lesser ex<SR>
  432. tent by other toolkits, and forms a component of specifications such 
  433. as COSE.
  434.  
  435. <"para">
  436.  
  437. The specification for Motif basically assumes a C-like language, and 
  438. the only imple<SR>
  439. mentation of that specification is the C library from OSF. This has 
  440. led to many bind<SR>
  441. ings to this library from alternative systems. These include C++, 
  442. Ada, Prolog, Lisp, <SR>
  443. Poplog and the Korn Shell.
  444.  
  445. <"para">
  446.  
  447. Tcl (Tool Command Language) is a type-free interpreted language that 
  448. was designed <SR>
  449. to be embedded into applications requiring a command language for 
  450. communication <SR>
  451. with users, to parse specification files requiring language complexity, 
  452. and to provide <SR>
  453. a macro language for applications such as spreadsheets. The intent 
  454. was to do it right <SR>
  455. once, so that application-writers need not invent their own language 
  456. and write their <SR>
  457. own parsers and semantic evaluators.
  458.  
  459. <"para">
  460.  
  461. Tcl has been extended with an X Window toolkit not based on the Intrinsics, 
  462. that sup<SR>
  463. plies a set of widgets directly accessible from tcl. This Tk toolkit 
  464. is generally run <SR>
  465. from a program called wish that sets up a suitable environment and 
  466. then calls an event <SR>
  467. processing loop for the Tk widgets.
  468.  
  469. <"para">
  470.  
  471. However, there are differences between Tk and Motif, some minor and 
  472. some major. <SR>
  473. These differences are no better nor worse than the differences between 
  474. other toolkits <SR>
  475. such as InterViews, but do seem to give rise to some heated debate 
  476. at times. For ex<SR>
  477. ample, there is the claim that Motif must be slower than Tk because 
  478. of the complexity <SR>
  479. of implementation above Xt. On the other hand, it must be faster because 
  480. Tcl/Tk is <SR>
  481. interpreted. Tcl/Tk programs are often pointed at as significantly 
  482. shorter than equiva<SR>
  483. lent Motif programs, without determining whether this difference is 
  484. caused by choice <SR>
  485. of language - C versus Tcl, or choice of toolkit - Motif versus Tk. 
  486. Other issues such <SR>
  487. as the complexity of Motif XmStrings against their value for internationalisati
  488. on are <SR>
  489. often discussed.
  490.  
  491. <"para">
  492.  
  493. <|,"2">This paper reports on a project that attempts to remove some 
  494. of the variables from <SR>
  495. this debate. It provides a binding of Tcl to Motif so that Tcl programs 
  496. can be written <SR>
  497. directly using the Motif C libraries. This binding is by a library 
  498. of C functions called <SR>
  499. tclMotif (Tcl Motif). The focus in this paper is on the mechanisms of this 
  500. implementation.
  501.  
  502. <"para">
  503.  
  504. Recently the author became aware of the Wafe system, which was a binding 
  505. of the <SR>
  506. Athena widgets to tcl. That project had different aims to this one, 
  507. but there are many <SR>
  508. common elements. This is also discussed.
  509.  
  510. <"section">
  511.  
  512. <"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, Value = "2."> 
  513. <End Sub><F0>Elements of tcl
  514.  
  515. <"para">
  516.  
  517. Tcl is an interpreted language with a single data type, string. 
  518. It is a command language, that is intended to be embedded into 
  519. applications requiring a simple language interface. 
  520. The syntax is a cross between `C' and the Unix shells, and it is a simple 
  521. and easy language to learn. 
  522. A typical program is the following, to find the maximum integer from a list 
  523. read in from standard input, one per line:
  524.  
  525. <"para">
  526.  
  527. proc max {a b} {<HR>
  528. <tab>if {$a > $b} return $a<HR>
  529. <tab>return $b<HR>
  530. }<HR>
  531. <HR>
  532. gets stdin maximum<HR>
  533. while {[gets stdin next] != -1} {<HR>
  534. <tab>set maximum [max $maximum $next]<HR>
  535. }<HR>
  536. puts stdout "maximum value is $maximum"<HR>
  537.  
  538. <"para">
  539.  
  540. Tcl is implemented as a library of `C' functions that can be linked in 
  541. with an application, often using a simple interpreter loop. 
  542. A large number of applications are now available using this command 
  543. language. 
  544. This reduces the need for the programmer to invent new languages, 
  545. and for the user to learn new ones.
  546.  
  547.  
  548. <"section">
  549.  
  550. <"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, Value = "4."> 
  551. <End Sub><F0>Elements of Tk
  552.  
  553. <"para">
  554.  
  555. Tk is a set of widgets built directly on X. 
  556. It is not based on the Intrinsics. 
  557. Like tcl, Tk is implemented as a library of `C' functions, 
  558. which can be linked with an application. 
  559. Thus it forms an embedded windowing library that uses tcl as main 
  560. programming language.
  561.  
  562. <"para">
  563.  
  564. The majority of Tk applications are written entirely in tcl, 
  565. and assume a standard application called wish. 
  566. wish is basically just an interpreter that creates the tcl and Tk worlds 
  567. and then enters an event loop, processing and despatching events 
  568. to the Tk widgets. 
  569. The behaviour and apearance of the widgets are described in tcl, 
  570. leading to very short and simple X Window programs.
  571.  
  572. <"para">
  573.  
  574. Applications requiring more complex behaviour than possible just with 
  575. wish and tcl can be built with additional code, incorporating the 
  576. wish interpreter as component. 
  577. In tcl version 7, a standard way has been defined to create such 
  578. extended applications for both tcl and Tk.
  579.  
  580.  
  581.  
  582. <"section">
  583.  
  584. <"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, Value = "5."> 
  585. <End Sub><F0>The <F11@Z7@Lam>moat<F0> Interpreter
  586.  
  587. <"para">
  588.  
  589. tclMotif is defined as a set of `C' functions that provide an interface 
  590. between tcl and the Motif library. 
  591. This set conforms to the extension standard, so acts as an extension 
  592. to the basic tcl interpreter. This extension is built as an application 
  593. called moat (MOtif and Tcl) and acts in a similar way to wish. 
  594. That is, most tclMotif applications can be written entirely in tcl, 
  595. but if needed additional functionality can be linked in easily.
  596.  
  597.  
  598. <"para">
  599.  
  600. The moat interpreter sets 
  601. up the tclMotif world so that commands are available to initialize 
  602. an Xt application <SR>
  603. context, create widgets and enter the Xt event loop. In early versions 
  604. the initialisation <SR>
  605. and loop were hidden as in Tk, but this reduced flexibility (such 
  606. as being unable to <SR>
  607. set the application class or fallback resources) and failed to 
  608. conform to the emerging way 
  609. for tcl extensions <SR>
  610. to be added.
  611.  
  612. <"section">
  613.  
  614. <"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, Value = "6."> 
  615. <End Sub><F0>Creating Widgets
  616.  
  617. <"para">
  618.  
  619. Widgets are created using Tcl commands registered with the Tcl interpreter 
  620. on initial<SR>
  621. isation.  These creation commands follow the design of the Tk system, 
  622. in that there <SR>
  623. is one creation command per class of widget. For example,
  624.  
  625. <"program">
  626.  
  627. xmLabel .label
  628.  
  629. <"para">
  630.  
  631. The widgets form a tree of widgets rooted in `.'. There is only one 
  632. application context <SR>
  633. per tcl interpreter but this does not seem to be a restriction.
  634.  
  635. <"para">
  636.  
  637.  In addition, Motif has a set of dialogs, which are convenience routines 
  638. for creating <SR>
  639. a compound widget in a way that is supposed to be invisible to the 
  640. C programmer and <SR>
  641. act as though they create single objects. These routines are also 
  642. implemented as wid<SR>
  643. get creation functions in tclMotif. It is not hard to ``special case'' some 
  644. functions within <SR>
  645. tclMotif to handle these dialogs. Motif also ``special cases'' two common 
  646. operations - <SR>
  647. creating a ScrolledList and a ScrolledText widget. This is also handled 
  648. by tclMotif. In <SR>
  649. both of these special cases, the parent is brought into the tclMotif system, 
  650. and is given a <SR>
  651. unique name. This name is produced from the pathname by introducing 
  652. an extra dot <SR>
  653. into the path.
  654.  
  655. <"section">
  656.  
  657. <"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, Value = "7."> 
  658. <End Sub><F0>Widget Commands
  659.  
  660. <"para">
  661.  
  662. When a widget is created two major things occur: an Xt/Motif widget 
  663. is created and <SR>
  664. a command with the widget name is added to the Tcl interpreter. This 
  665. gives an object-<SR>
  666. <|,"3">oriented flavour to the system in that a widget becomes a command 
  667. which is inter<SR>
  668. preted as an object with methods.
  669.  
  670. <"section">
  671.  
  672. <"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, Value = "8."> 
  673. <End Sub><F0>Widget Methods
  674.  
  675. <"para">
  676.  
  677. Each widget has a set of methods applicable to it. In general, most 
  678. widgets inherit <SR>
  679. from TmCore. This allows Xt methods such as <"program", Subcomponent = yes>
  680. <F7@Z7@Lam>ManageChild<End Sub><F0> and <"program", Subcomponent = yes><F7@Z7@Lam>
  681. Unmanage<SR>
  682. Child<End Sub><F0> to be handled from one function.  The design of 
  683. Tcl registers a command han<SR>
  684. dler per command; widgets that have no special methods simply register 
  685. the <"program", Subcomponent = yes><F7@Z7@Lam>TmCore<End Sub><F0> <SR>
  686. handler. Widgets with more methods register a different handler which 
  687. may call <SR>
  688. <"program", Subcomponent = yes><F7@Z7@Lam>TmCore<End Sub><F0> eventually 
  689. in an inheritance chain.
  690.  
  691. <"para">
  692.  
  693. Each widget in fact has special methods: the callback procedures for 
  694. that class. This <SR>
  695. is handled by <"program", Subcomponent = yes><F7@Z7@Lam>TmCore
  696. <End Sub><F0> rather than in individual command handlers because of 
  697. regu<SR>
  698. larities in the implementation of Motif that are better discussed 
  699. in the next section. <SR>
  700. Briefly, each callback can be recognised because it ends in the string 
  701. ``Callback''. <SR>
  702. This can then be added to the Xt widget callbacks using 
  703. <"program", Subcomponent = yes><F7@Z7@Lam>XtAddCallback<End Sub><F0> 
  704. in the <SR>
  705. <"program", Subcomponent = yes><F7@Z7@Lam>TmCore<End Sub><F0> handler, 
  706. without worrying about exactly which callback it is.
  707.  
  708. <"para">
  709.  
  710. In C, when a callback is added to a widget a specific C function is 
  711. specified that will <SR>
  712. be invoked when the action for that callback occurs. However, we want 
  713. a Tcl function <SR>
  714. to be executed. This is easily done by using a generic C callback 
  715. function that handles <SR>
  716. every widget, almost without exception. When a callback is added in 
  717. Xt, the <SR>
  718. <"program", Subcomponent = yes><F7@Z7@Lam>ClientData<End Sub><F0> 
  719. field is set to point to a structure containing the Tcl interpreter 
  720. and <SR>
  721. the string that is the Tcl callback function. This gives the generic 
  722. C callback function <SR>
  723. enough information to execute the Tcl function.
  724.  
  725. <"section">
  726.  
  727. <"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, Value = "9."> 
  728. <End Sub><F0>Resource Converters
  729.  
  730. <"para">
  731.  
  732. The presence of resource converters within Xt is the key to the ease 
  733. with which this <SR>
  734. binding has been implemented. Previous sections have used existing 
  735. Tcl/Tk concepts <SR>
  736. (and code) to a large extent. It is now time for Xt to play a significant 
  737. part. Xt allows <SR>
  738. users to store resource values in files such as 
  739. <"program", Subcomponent = yes><F7@Z7@Lam>.Xdefaults<End Sub><F0> 
  740. to control run-time val<SR>
  741. ues for the program. This user-level control is one of the major features 
  742. of Xt. The <SR>
  743. resource files contain strings representing the values the user wants. 
  744. For example, a <SR>
  745. width may be set to the string ``200". Xt, and all toolkits built 
  746. above it, supply ``re<SR>
  747. source converters'' to transform these string values into the internal 
  748. data types re<SR>
  749. quired by the program.
  750.  
  751. <"para">
  752.  
  753. To perform such conversions, Xt supplies a number of useful functions. 
  754. <"program", Subcomponent = yes><F7@Z7@Lam>XtGetRe<SR>
  755. sourceList<End Sub><F0> and <"program", Subcomponent = yes><F7@Z7@Lam>XtGetCons
  756. traintList<End Sub><F0> return lists of resources applicable <SR>
  757. to each class of widget. Elements in these lists are structures that 
  758. contain strings rep<SR>
  759. resenting the source and destination types, and the size (in bytes) 
  760. of the destination <SR>
  761. type. The string representations allow searches for source types, 
  762. and the structure <SR>
  763. when located in the list provides enough information to call 
  764. <"program", Subcomponent = yes><F7@Z7@Lam>XtConvertAnd<SR>
  765. Store<End Sub><F0>. This looks up a list of registered converters 
  766. and calls the converter function <SR>
  767. if found.
  768.  
  769. <"para">
  770.  
  771. This makes one side of this binding trivially simple: if a resource 
  772. can be specified <SR>
  773. in a resource file then a converter exists from string to internal 
  774. value. The Tcl <"program", Subcomponent = yes><F7@Z7@Lam>set<SR>
  775. Values<End Sub><F0> method simply has to locate the resource in 
  776. these resource lists and call <SR>
  777. <|,"4"><"program", Subcomponent = yes><F7@Z7@Lam>XtConvertAndStore
  778. <End Sub><F0>. It can then use  <"program", Subcomponent = yes><F7@Z7@Lam>XtSet
  779. Values<End Sub><F0> to install the converted <SR>
  780. value, and Xt and Motif do the rest!
  781.  
  782. <"para">
  783.  
  784. This also makes the naming conventions in tcl very easy. Because resources 
  785. are spe<SR>
  786. cified as strings, the names can be used by tcl without change. Motif 
  787. and Xt are quite consis<SR>
  788. tent in its use of these names (alphabetic only, beginning with a 
  789. lower case letter, and <SR>
  790. with other words in the name capitalised). Tk uses this convention 
  791. as well, so the sim<SR>
  792. ilarity in programs across the two systems is maintained.
  793.  
  794. <"para">
  795.  
  796. Well, it isn't really trivial. Some resources require widget values, 
  797. such as edge bind<SR>
  798. ings in Form. tclMotif needs to supply another converter, from TmWidgetName 
  799. to Xt <SR>
  800. Widget. This, and similar needs are answered by just adding more converters. 
  801. A more <SR>
  802. serious problem is addressed in the next section.
  803.  
  804. <"para">
  805.  
  806. The largest amount of work in this binding is in implementing 
  807. <"program", Subcomponent = yes><F7@Z7@Lam>getValues<End Sub><F0>. 
  808. This <SR>
  809. requires conversion from internal type to strings. For many types 
  810. such as Dimension <SR>
  811. there is no support from either Xt or Motif. However, for enumerated 
  812. types such as <SR>
  813. arrowDirection for the ArrowButton widget, Motif 1.2 not only gives 
  814. ``Representa<SR>
  815. tion Type'' converters for conversion from String to enumerated type, 
  816. but also allows <SR>
  817. converters in the reverse direction to be installed, so that names 
  818. such as <"program", Subcomponent = yes><F7@Z7@Lam>ar<SR>
  819. row_left<End Sub><F0>' can be generated. This was intended for GUI 
  820. building systems which <SR>
  821. need to use symbolic names when setting or getting widget values, 
  822. but it suits tclMotif very <SR>
  823. well, thank you.
  824.  
  825. <"section">
  826.  
  827. <"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, Value = "10."> 
  828. <End Sub><F0>Secondary Resources
  829.  
  830. <"para">
  831.  
  832. Xt allows objects to have subobjects. There are not many examples 
  833. of these. Editors <SR>
  834. with Output subobjects and Input subobjects are the principal ones. 
  835. The nasty part <SR>
  836. is that these subobjects can have their own resources and Xt supplies 
  837. no means for <SR>
  838. an application to access them. Xt has a ``hook'' to allow the toolkit 
  839. library to access <SR>
  840. them, but not the application (in Motif at any rate they are static 
  841. to a file, so there is <SR>
  842. no direct way of accesing them). Fortunately, Motif (not Xt) supplies 
  843. the function <SR>
  844. <"program", Subcomponent = yes><F7@Z7@Lam>XmGetSecondaryResources
  845. <End Sub><F0> to get these.
  846.  
  847. <"section">
  848.  
  849. <"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, Value = "11."> 
  850. <End Sub><F0>Callback Information
  851.  
  852. <"para">
  853.  
  854. In the Motif callbacks, a rich amount of information is conveyed through 
  855. the call_data argument. Each call_data structure contains a number of 
  856. fields with information specific to the type of widget and the reason 
  857. the callback was called. For example, the List widget contains a reason 
  858. field with possible values of XmCR_SINGLE_SELECT, XmCR_EXTENDED_SELECT, 
  859. XmCR_BROWSE_SELECT, etc. Additional fields give the item selected, the 
  860. the selected item position, list of items selected, their positions,  
  861. and the number of items. Other useful information contained in a 
  862. callback includes the widget. These are accessible to the tcl code 
  863. declared to the callback by substitutions based on simple patterns.
  864.  
  865. <"section">
  866.  
  867. <"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, Value = "11."> 
  868. <End Sub><F0>Text Verify Callbacks
  869.  
  870. <"para">
  871.  
  872. Motif callbacks, as discussed, provide extra information through the 
  873. callback data structures. 
  874. Generally these structures contain ``read 
  875. only'' informa<SR>
  876. tion that is not to be modified. These can be passed by value by just 
  877. substitution of the value.
  878.  
  879. <"para">
  880.  
  881. The Text widget has a set of ``verify'' callbacks that point to read/write  
  882. structures. <SR>
  883. The purpose of these is to allow for things such as password entry, 
  884. where the applica<SR>
  885. tion needs to be given the characters typed in, but must be able to 
  886. signal to Text not <SR>
  887. to echo these characters. This is done by setting the 
  888. <"program", Subcomponent = yes><F7@Z7@Lam>doit<End Sub><F0> field 
  889. in the <"program", Subcomponent = yes><F7@Z7@Lam>XmTextVer<SR>
  890. ifyCallbackStruct<End Sub><F0> to <"program", Subcomponent = yes><F7@Z7@Lam>Fal
  891. se<End Sub><F0>. These callbacks are actually called by Motif in <SR>
  892. a slightly unusual way: for example, when characters are typed in 
  893. Motif decodes the <SR>
  894. characters, calls the <"program", Subcomponent = yes><F7@Z7@Lam>modifyVerifyCal
  895. lbacks<End Sub><F0>, examines the return state of the <SR>
  896. callback structure and only then actually inserts (or not) the characters 
  897. typed.
  898.  
  899. <"para">
  900.  
  901. This is handled by creating a variable global in the tcl interpreter 
  902. and passing its name <SR>
  903. (rather than its value) into the callback. The application can then 
  904. modify its value, <SR>
  905. and this is used to set the Motif fields as appropriate. The Motif 
  906. mechanism is odd <SR>
  907. in this respect, and the tcl binding shows this in practice. Since 
  908. the variable is only <SR>
  909. defined in the tcl intrepreter it does not prevent multiple interpreters 
  910. running.
  911.  
  912. <"section">
  913.  
  914. <"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, Value = "11."> 
  915. <End Sub><F0>Other Handlers
  916.  
  917. <"para">
  918.  
  919. The Intrinsics allow a number of other ways of controlling applications, 
  920. through timers, input handlers and action control. These are all dealt 
  921. with in tclMotif by registering generic handlers which take arbitrary 
  922. tcl code and call it as appropriate. 
  923. For example, Motif popup menus require a popup action to be triggered 
  924. when button 3 is pressed. This popup action must take the event that 
  925. caused it to be used to position the menu. This is done in tclMotif by
  926. defining a translation to invoke the action:
  927.  
  928. <"para">
  929.  
  930. $w setValues -translations \<HR>
  931. <Tab>"<<Btn3Down>: action(popit %event)
  932.  
  933. <"para">
  934.  
  935. Similarly, an input handler is added by
  936.  
  937. <"para">
  938.  
  939. . addInput file.txt r readInput
  940.  
  941. <"para">
  942.  
  943. and a timer by
  944.  
  945. <"para">
  946.  
  947. . addTimer 1000 quit
  948.  
  949.  
  950. <"section">
  951.  
  952. <"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, Value = "11."> 
  953. <End Sub><F0>Convenience functions
  954.  
  955. <"para">
  956.  
  957. Motif supplies convenience functions of several 
  958. types. <SR>
  959. Some such as the various RowColumn functions of 
  960. <"program", Subcomponent = yes><F7@Z7@Lam>XmCreateMenuBar
  961. <End Sub><F0>, <SR>
  962. <"program", Subcomponent = yes><F7@Z7@Lam>XmCreateOptionMenu
  963. <End Sub><F0>, etc just set extra parameters for RowColumn and are <SR>
  964. easy to handle. Two other sets are the ScrolledObject functions such 
  965. as <"program", Subcomponent = yes><F7@Z7@Lam>XmCrea<SR>
  966. teScrolledList<End Sub><F0> and <"program", Subcomponent = yes><F7@Z7@Lam>XmCre
  967. ateScrolledText<End Sub><F0> and the Dialog conve<SR>
  968. nience functions such as <"program", Subcomponent = yes><F7@Z7@Lam>XmCreateForm
  969. Dialog<End Sub><F0> etc. Both of these sets of func<SR>
  970. tions create a pair of widgets, not just a single one. For example, 
  971. <"program", Subcomponent = yes><F7@Z7@Lam>XmCreateS<SR>
  972. crolledList<End Sub><F0> creates a ScrolledWindow parent and the List 
  973. child, whereas the <SR>
  974. Dialog functions create a Popup shell parent. In all cases, the Create 
  975. function returns <SR>
  976. the child widget.
  977.  
  978. <"para">
  979.  
  980. The intent in Motif was to hide the parent widgets. Unfortunately 
  981. it canot be done <SR>
  982. completely for several reasons. Firstly, when the ScrolledList (or 
  983. any of the others) <SR>
  984. is destroyed, it is the parent that must be destroyed, not just the 
  985. child. Otherwise a <SR>
  986. <|,"5">memory leak occurs. Secondly, when you need to set constraint 
  987. resources (such as <SR>
  988. placing the ScrolledList into a Form), it is the parent widget that 
  989. needs resources set, <SR>
  990. not the child. Thus a mechanism to access the parent is required.
  991.  
  992. <"para">
  993.  
  994. In Motif, this may be done by the call <"program", Subcomponent = yes><F7@Z7@Lam>
  995. XtParent<End Sub><F0>, which returns the Xt widget par<SR>
  996. ent. In this binding it is neccessary to return a tcl widget parent, 
  997. and this may be a <SR>
  998. problem. The tcl parent must be generated automatically, but must 
  999. be guaranteed <SR>
  1000. unique. Otherwise there may be an accidental name collision with other 
  1001. tcl widgets. <SR>
  1002. The Motif naming mechanism (tacking ``SW'' onto Scrolled Objects, 
  1003. ``_popup'' <SR>
  1004. onto dialogs) does not guarantee this. Fortunately, the particular 
  1005. naming syntax used <SR>
  1006. in this binding (based on Tk), where widget names are separated by 
  1007. dots ``.'' does <SR>
  1008. allow this, by inserting an extra dot. For example,
  1009.  
  1010. <"program">
  1011.  
  1012. scrolledList .l<HR>
  1013. puts stdout [.l parent]
  1014.  
  1015. <"para">
  1016.  
  1017. produces the unique `..l''.
  1018.  
  1019.  
  1020. <"section">
  1021.  
  1022. <"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, Value = "12."> 
  1023. <End Sub><F0>Inconsistencies and Problems
  1024.  
  1025. <"subsection">
  1026. Actions
  1027.  
  1028. <"para">
  1029.  
  1030. tcl is designed so that multiple interpreters can be created and run 
  1031. together. All information is contained in one data structure per 
  1032. interpreter, that is passed into each `C' function. tclMotif attempts 
  1033. to follow this pattern. This means avoiding global variables and 
  1034. registering information with either with the tcl interpreter or in 
  1035. such a way that it and the tcl interpreter are accessible.
  1036.  
  1037. <"para">
  1038.  
  1039. For callback functions this is easy: when a callback 
  1040. is registered the client_data field is set to a structure that contains the 
  1041. interpreter as well a sthe tcl command. This allows the per interpreter 
  1042. information to be carried into the callback functions.
  1043.  
  1044.  
  1045. <"para">
  1046.  
  1047. When an action function is registered, there is no client data field to 
  1048. pass the interpreter by. There is only the widget and the action function
  1049. itself. Fortunately, Motif offers a solution in that each Motif widget 
  1050. contains an XmNuserData resource that can be used to store arbitrary data. 
  1051. This is used in tclMotif to store a structure including the tcl interpreter, 
  1052. so that all necessary information can be retrieved. This does have 
  1053. the drawback that this restricts use of this system to the Motif widget 
  1054. set, or to a set based on it. The WAFE system uses global variables 
  1055. to handle the Athena set. There is another storage mechanism: the Context 
  1056. manager of Xlib, but this requires windows to be in existence, which in 
  1057. turn would require realized widgets. This cannot always be guaranteed.
  1058.  
  1059.  
  1060. <"subsection">
  1061.  
  1062. Tables
  1063.  
  1064. <"para">
  1065.  
  1066. By and large tcl and Motif work well together. One area that does 
  1067. not integrate per<SR>
  1068. fectly concerns tables. In Motif there are sometimes tables of 
  1069. <"program", Subcomponent = yes><F7@Z7@Lam>XmStrings<End Sub><F0>, 
  1070. and when <SR>
  1071. they are represented as strings individual elements are separated 
  1072. by commas.  tcl on <SR>
  1073. the other hand represents lists as elements separated by whitespace.  
  1074. Both handle lists <SR>
  1075. containing whitespace in different ways, with the tcl solution being 
  1076. more general. (X11R6 looks set to introduce a third convention into 
  1077. this, with StringTables of strings separated by spaces.)<SR>
  1078. Motif would have (say for a list of authors of Motif books)
  1079.  
  1080. <"program">
  1081.  
  1082. Dan Heller, Jan Newmarch, Thomas Berlage
  1083.  
  1084. <"para">
  1085.  
  1086. tcl would have
  1087.  
  1088. <"program">
  1089.  
  1090. {Dan Heller} {Jan Newmarch} {Thomas Berlage}
  1091.  
  1092. <"para">
  1093.  
  1094. An arbitrary convention has to be chosen. Currently this follows the 
  1095. Motif style, but may change to the tcl style in a later version.
  1096.  
  1097. <"subsection">
  1098.  
  1099. Timing conversions
  1100.  
  1101. <"para">
  1102.  
  1103. Some resources can only be set at creation time. Such resources are 
  1104. of two types: the <SR>
  1105. first is exemplified by the colormap in which the value of this resource is 
  1106. used during the Initial<SR>
  1107. ize function and is thereafter unused. The second is one that cannot 
  1108. be changed be<SR>
  1109. cause it has too many ramifications. Such a resource is the 
  1110. <"program", Subcomponent = yes><F7@Z7@Lam>ScrollingPolicy
  1111. <End Sub><F0> of <SR>
  1112. the ScrolledWindow widget. These resources must be converted from 
  1113. their String <SR>
  1114. value to be used in the <"program", Subcomponent = yes><F7@Z7@Lam>Args
  1115. <End Sub><F0> array to the <"program", Subcomponent = yes><F7@Z7@Lam>XmCreate..
  1116. .<End Sub><F0> function.
  1117.  
  1118. <"para">
  1119.  
  1120. On the other hand, some resources use widget values in their calculation. 
  1121. For exam<SR>
  1122. ple, any <"program", Subcomponent = yes><F7@Z7@Lam>Dimension
  1123. <End Sub><F0> or <"program", Subcomponent = yes><F7@Z7@Lam>Position
  1124. <End Sub><F0> resource such as the <"program", Subcomponent = yes><F7@Z7@Lam>wi
  1125. dth<End Sub><F0> uses the Motif <SR>
  1126. <"program", Subcomponent = yes><F7@Z7@Lam>UnitType<End Sub><F0> resource 
  1127. in its calculation, in order to gain independance of the display <SR>
  1128. size characteristics. Similarly, the <"program", Subcomponent = yes><F7@Z7@Lam>
  1129. LabelPixmap<End Sub><F0> resource of Labels needs to have <SR>
  1130. a foreground and background before it can be created.
  1131.  
  1132. <"para">
  1133.  
  1134. These differing cases cause a problem. The convertor functions from 
  1135. String to Value <SR>
  1136. use a widget parameter, and in the first case this can only be the 
  1137. parent (as the child <SR>
  1138. Create function cannot have been called yet) whereas in the second 
  1139. it requires the <SR>
  1140. widget itself. The special case code to handle this is not only a 
  1141. maintainance problem, <SR>
  1142. but is not guaranteed to be correct in the first place as neither 
  1143. Motif nor Xt offer any <SR>
  1144. support to distinguish the cases (an early version of the WKSH also 
  1145. faced this problem <SR>
  1146. and missed the <"program", Subcomponent = yes><F7@Z7@Lam>LabelPixmap
  1147. <End Sub><F0> case, probably because it is quite well hidden in the <SR>
  1148. Motif source).
  1149.  
  1150. <"para">
  1151.  
  1152. This binding divides the resources into ones which must be converted 
  1153. before cre<SR>
  1154. ation, those that must be converted after creation, and those for 
  1155. which it does not mat<SR>
  1156. ter. These are all handled correctly. A case which is not handled 
  1157. is where the conver<SR>
  1158. sion must be done <F4@Z7@Lam>during<F0> creation. Fortunately this 
  1159. does not occur, as it would break <SR>
  1160. any bindings such as this one that rely on the resource converter 
  1161. mechanism.
  1162.  
  1163. <"subsection">
  1164.  
  1165. XmStringTables
  1166.  
  1167. <"para">
  1168.  
  1169. Various widgets such as ScrolledList use <"program", Subcomponent = yes><F7@Z7@Lam>
  1170. XmStringTables<End Sub><F0>, which are arrays of <SR>
  1171. <"program", Subcomponent = yes><F7@Z7@Lam>XmStrings<End Sub><F0>. 
  1172. Motif is inconsistent in its internal use of these arrays - sometimes <SR>
  1173. they are NULL-terminated, most times they are not. This means that 
  1174. there is no way <SR>
  1175. <|,"6">of determining from the <"program", Subcomponent = yes><F7@Z7@Lam>XmStri
  1176. ngTable<End Sub><F0> itself exactly how many elements it con<SR>
  1177. tains. This must be found from other means. For example, the size 
  1178. of the List resource <SR>
  1179. <"program", Subcomponent = yes><F7@Z7@Lam>items<End Sub><F0> is found 
  1180. in the List resource <"program", Subcomponent = yes><F7@Z7@Lam>itemCount
  1181. <End Sub><F0>, and the size of the <"program", Subcomponent = yes><F7@Z7@Lam>se
  1182. lectedI<SR>
  1183. tems<End Sub><F0> resource is found in the <"program", Subcomponent = yes>
  1184. <F7@Z7@Lam>`selectedItemsCount<End Sub><F0> resource. When an <SR>
  1185. <"program", Subcomponent = yes><F7@Z7@Lam>XmStringTable<End Sub><F0> 
  1186. is converted into a <"program", Subcomponent = yes><F7@Z7@Lam>String
  1187. <End Sub><F0>, this size must be known to the re<SR>
  1188. source converter. This could be determined from the widget type and 
  1189. resource name <SR>
  1190. (eg for <"program", Subcomponent = yes><F7@Z7@Lam>items<End Sub><F0> 
  1191. of a List widget, determine it from <"program", Subcomponent = yes><F7@Z7@Lam>i
  1192. temCount<End Sub><F0>), but the resource <SR>
  1193. name is not available to the resource converter. Thus special case 
  1194. code must be in<SR>
  1195. serted before any  resource converter can be called, just in case 
  1196. it is one of these cases. <SR>
  1197. This is inelegant and an overhead in time for all of the resource 
  1198. conversions, whatev<SR>
  1199. er type.
  1200.  
  1201.  
  1202. <"subsection">
  1203.  
  1204. Drag and drop
  1205.  
  1206. <"para">
  1207.  
  1208. The Motif 1.2 drag and drop model is extremely complex. It uses complex 
  1209. informa<SR>
  1210. tion flows and even utilises a data structure <"program", Subcomponent = yes>
  1211. <F7@Z7@Lam>XmDropSite<End Sub><F0> that is neither a widget <SR>
  1212. nor an Xt object. It is impossible to keep interpreter information 
  1213. hidden as the <SR>
  1214. XmDropSite data structure does not contain a <"program", Subcomponent = yes>
  1215. <F7@Z7@Lam>user_data<End Sub><F0> field. Use of a temporary <SR>
  1216. global variable here is a kludge, but does not seem to be a dangerous 
  1217. one.
  1218.  
  1219. <"section">
  1220.  
  1221. <"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, Value = "13."> 
  1222. <End Sub><F0>Hiding Complexity
  1223.  
  1224. <"para">
  1225.  
  1226. One of the hurdles in any Xt program is the complexity of concepts 
  1227. in even a trivial <SR>
  1228. program. For example, the function <"program", Subcomponent = yes><F7@Z7@Lam>Xt
  1229. AppInitialize<End Sub><F0> has <F4@Z7@Lam>nine<F0> parameters, <SR>
  1230. most of which do not change from program to program. The tclMotif 
  1231. library can hide <SR>
  1232. much of this complexity by supplying reasonable defaults that can 
  1233. be overridden if <SR>
  1234. needed by options to tcl commands.
  1235.  
  1236. <"para">
  1237.  
  1238. Motif adds further layers of complexity above this. A particularly 
  1239. tricky  hurdle to <SR>
  1240. overcome is the support for internationalisation offered by 
  1241. <"program", Subcomponent = yes><F7@Z7@Lam>XmStrings<End Sub><F0>. 
  1242. The tclMotif <SR>
  1243. library handles XmStrings internally, and uses the normal tcl String 
  1244. mechanism for <SR>
  1245. all purposes. Thus this mechanism is hidden from the tcl programmer. 
  1246. It is still pres<SR>
  1247. ent in Motif, so a Label widget can display Japanese text as specified 
  1248. in a resource <SR>
  1249. file. The ability of tcl to manage this is still in doubt (it is at 
  1250. least 8-bit clean, and Tk <SR>
  1251. can use the X11 support to display ISO 8859-1 characters).
  1252.  
  1253. <"para">
  1254.  
  1255. Some example programs built with tclMotif include a version of the file 
  1256. manager xmfm; xmeditor; widget tour; editres. The tcl version of xmfm 
  1257. is about 700 lines. This represents the `C' version when it had about 
  1258. 7000 lines. The tcl version of xmeditor is about 300 lines. The `C' version 
  1259. as given in the examples of the Motif distribution is about 1200 lines.
  1260. The tcl version of the Tk widget tour is about the same length. A program 
  1261. which can display resources of  an application, much like editres does, 
  1262. uses Tk's send to communicate to the other application, and is 130 lines 
  1263. long.
  1264.  
  1265. <"section">
  1266.  
  1267. <"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, Value = "14."> 
  1268. <End Sub><F0>Validation
  1269.  
  1270. <"para">
  1271.  
  1272. The tclMotif library is built on Motif. Can it be certified as Motif compliant? 
  1273. Well, actual<SR>
  1274. ly, no. This is basically a library into Motif, and as such must be 
  1275. compliant with the <SR>
  1276. AES (Application Environment Specification). The AES details what 
  1277. functions a <SR>
  1278. Motif library must make available, and this binding falls short of 
  1279. that. For example, <SR>
  1280. tclMotif hides <"program", Subcomponent = yes><F7@Z7@Lam>XmStrings
  1281. <End Sub><F0> and has no explicit support for them. So it fails the 
  1282. test of <SR>
  1283. ``coverage'' as you can't do everything in tclMotif that you can using the 
  1284. OSF C library.
  1285.  
  1286. <"para">
  1287.  
  1288. On the other hand, applications built using this library can be certified 
  1289. as Motif com<SR>
  1290. pliant. Application compliance just means that <F4@Z7@Lam>out of the 
  1291. elements of GUI used<F0>, these <SR>
  1292. conform to the Motif Style Guide. You can really muck up a tclMotif application 
  1293. by putt<SR>
  1294. ing the menu bar at the bottom, with the Help button on the left and 
  1295. even worse things, <SR>
  1296. and these will fail to  give you Motif compliance, but if you aren't 
  1297. that silly you will <SR>
  1298. be able to get Motif certification for applications built using tclMotif.
  1299.  
  1300. <"section">
  1301.  
  1302. <|,"8"><"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, Value = "15."> 
  1303. <End Sub><F0>Wafe and WKSH
  1304.  
  1305. <"para">
  1306.  
  1307. The WKSH is a binding of the Korn Shell to Motif. It deals with the 
  1308. same problems <SR>
  1309. as this binding, in that it has to convert Strings to Motif types. 
  1310. It appears to use the <SR>
  1311. same mechanisms, and has run into the same problems. For example, 
  1312. it handles the <SR>
  1313. Conversion versus Creation problem for resources such as width by 
  1314. disallowing set<SR>
  1315. ting of such resources during creation! In this binding it is deferred 
  1316. until it is valid. <SR>
  1317. The lack of support by Xt and Motif in this area is evidenced by the 
  1318. failure of the <SR>
  1319. WKSH to correctly handle the <"program", Subcomponent = yes><F7@Z7@Lam>LabelPix
  1320. map<End Sub><F0> resource in its initial release.
  1321.  
  1322. <"para">
  1323.  
  1324. WKSH models itself on the syntax of the Motif C language binding. 
  1325. The function <SR>
  1326. calls use the same names, such as <"program", Subcomponent = yes><F7@Z7@Lam>XmC
  1327. reateMainWindow<End Sub><F0>. The binding also part<SR>
  1328. ly preserves the positional syntax of the C language, so that a C 
  1329. call
  1330.  
  1331. <"program">
  1332.  
  1333. w = XmCreateLabel(parent, name, args, argc)
  1334.  
  1335. <"para">
  1336.  
  1337. becomes
  1338.  
  1339. <"program">
  1340.  
  1341. XmCreateLabel parent w name args...
  1342.  
  1343. <"para">
  1344.  
  1345. The WKSH binding actually adds an extra argument to replace the return 
  1346. value of <SR>
  1347. the function, and uses the varargs style of argument passing that 
  1348. has become quite <SR>
  1349. popular within the X world. In calls with a large number of arguments, 
  1350. the use of posi<SR>
  1351. tional parameters can be difficult.
  1352.  
  1353. <"para">
  1354.  
  1355. The WKSH binding follows this action/object style even further in 
  1356. defining func<SR>
  1357. tions such as <"program", Subcomponent = yes><F7@Z7@Lam>XtManageChildren
  1358. <End Sub><F0> which place the action followed by arguments.
  1359.  
  1360. <"para">
  1361.  
  1362. The Wafe binding follows this same principle of action followed by 
  1363. object, but with<SR>
  1364. out the positional argument complexity of WKSH. This particular binding 
  1365. seems to <SR>
  1366. have suffered confused press in that it produces a Tcl binding to 
  1367. Xt on one side, and <SR>
  1368. an open-ended binding of Tcl/Xt to almost any language on the other. 
  1369. This generality <SR>
  1370. seems to have led to impressions such as ``it is a way of writing 
  1371. Perl programs that <SR>
  1372. use Tcl to talk to Xt''. The current status of Wafe is that it binds 
  1373. Tcl to a variety of <SR>
  1374. Xt-based widget libraries, with Athena being well supported, and Motif 
  1375. in beta. The <SR>
  1376. Wafe callback model is very different to tclMotif. In tclMotif, the Motif style 
  1377. is followed in <SR>
  1378. that the callback contains useful information and helps to give the 
  1379. ``feel'' part of the <SR>
  1380. ``look and feel'' paradigm. Wafe uses a limited set of callbacks to 
  1381. produce popup dia<SR>
  1382. logs.
  1383.  
  1384. <"para">
  1385.  
  1386. In implementation, the Wafe and tclMotif systems follow very similar lines 
  1387. as there is <SR>
  1388. really only one way of doing much of the binding of Xt toolkits to 
  1389. string languages <SR>
  1390. such as Tcl and Ksh. The authors of Wafe suffer the problem of only 
  1391. having access <SR>
  1392. to Motif 1.1 at the time of writing, so the additional aids supplied 
  1393. in Motif 1.2 are not <SR>
  1394. available to them. This is a distinct drawback. I am in email correspodence 
  1395. with them, <SR>
  1396. to avoid duplicating work.
  1397.  
  1398. <"section">
  1399.  
  1400. <"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, Value = "16."> 
  1401. <End Sub><F0>Conclusion
  1402.  
  1403. <"para">
  1404.  
  1405. This paper has discussed a binding of tcl to Motif. A large part of 
  1406. this binding is quite <SR>
  1407. trivial and follows almost automatically from the way Xt and Motif 
  1408. are implemented. <SR>
  1409. Every string-based language can have a binding done in a similar way. 
  1410. However, <SR>
  1411. there is still flexibility in this, particularly in the choice of 
  1412. object/action versus action/<SR>
  1413. object prorgamming.
  1414.  
  1415. <"para">
  1416.  
  1417. <|,"9">This binding has shown up a number of minor bugs in Motif, 
  1418. but also some design <SR>
  1419. problems in both Xt and Motif with regard to string-based languages. 
  1420. Nevertheless, <SR>
  1421. there seem to be no unresolvable problems in mapping a significant 
  1422. amount of Motif <SR>
  1423. into tcl.
  1424.  
  1425. <"section">
  1426.  
  1427. <"|:section", Subcomponent = yes><F0><Autonum, "section#", 1, Value = "17."> 
  1428. <End Sub><F0>References
  1429.  
  1430. <"reference">
  1431.  
  1432. <"|:reference", Subcomponent = yes><F0>[<Autonum, "ref#", 1, First = Yes, Value = "1">
  1433. ]<Tab><End Sub><F0>J. K. Ousterhout, <F4@Z7@Lam>Tcl: An Embeddable 
  1434. Command Lnaguage<F0>, Proc USENIX <SR>
  1435. Winter Conferenece January 1990.
  1436.  
  1437. <"reference">
  1438.  
  1439. <"|:reference", Subcomponent = yes><F0>[<Autonum, "ref#", 1, Value = "2">]<Tab>
  1440. <End Sub><F0>Jp. K. Ousterhout, <F4@Z7@Lam>An X11 Toolkit Based on 
  1441. the Tcl Lnaguage<F0>, Proc USENIX <SR>
  1442. Winter Conference, January 1991.
  1443.  
  1444. <"reference">
  1445.  
  1446. <"|:reference", Subcomponent = yes><F0>[<Autonum, "ref#", 1, Value = "3">]<Tab>
  1447. <End Sub><F0>G. Neumann and S. Nusser, <F4@Z7@Lam>Wafe - an X Toolkit 
  1448. Based Frontend for Applica<SR>
  1449. tion Programs in Various Programming Languages<F0>, Proc USENIX Winter <SR>
  1450. Conference, January 1993.
  1451.  
  1452. <"reference">
  1453.  
  1454. <"|:reference", Subcomponent = yes><F0>[<Autonum, "ref#", 1, Value = "4">]<Tab>
  1455. <End Sub><F0>J.S. Prendergast, <F4@Z7@Lam>Korn Shell with X Winfdows 
  1456. Support<F0>, Proc USING Confer<SR>
  1457. ence, 1992.
  1458.  
  1459. <"reference">
  1460.  
  1461. <"|:reference", Subcomponent = yes><F0>[<Autonum, "ref#", 1, Value = "5">]<Tab>
  1462. <End Sub><F0>J. S. Prendergast, <F4@Z7@Lam>Using Windowing Korn Shell 
  1463. for Turnkey Systems<F0>, Xhibi<SR>
  1464. tion 1992.
  1465.  
  1466. <"reference">
  1467.  
  1468. <"|:reference", Subcomponent = yes><F0>[<Autonum, "ref#", 1, Value = "6">]<Tab>
  1469. <End Sub><F0>Open Software Foundation, <F4@Z7@Lam>Application Environment 
  1470. Specification<F0>, Pren<SR>
  1471. tice-Hall.
  1472.  
  1473.  
  1474. <"reference">
  1475.  
  1476. <"|:reference", Subcomponent = yes><F0>[<Autonum, "ref#", 1, Value = "7">]<Tab>
  1477. <End Sub><F0>R. W. Scheifler, J. Gettys and R. Newman, 
  1478. <F4@Z7@Lam>X Window System - C Library and Protocol Reference
  1479. <F0>, Digital Press, 1988.
  1480.  
  1481.  
  1482.  
  1483. <"reference">
  1484.  
  1485. <"|:reference", Subcomponent = yes><F0>[<Autonum, "ref#", 1, Value = "8">]<Tab>
  1486. <End Sub><F0>P. Asente and R. Swick, <F4@Z7@Lam>X Window System Toolkit, the 
  1487. Complete Programmer's Guide and Specification<F0>, Digital Press, 1990.
  1488.  
  1489.  
  1490. <"reference">
  1491.  
  1492. <"|:reference", Subcomponent = yes><F0>[<Autonum, "ref#", 1, Value = "9">]<Tab>
  1493. <End Sub><F0>D. Beech, <F4@Z7@Lam>IFIP Conference on Command Languages, 1979.
  1494.  
  1495.